package com.jweb.framework.ws.support;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import javax.xml.namespace.QName;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamSource;

import org.apache.ws.commons.schema.XmlSchema;
import org.apache.ws.commons.schema.XmlSchemaCollection;
import org.apache.ws.commons.schema.XmlSchemaSerializer;
import org.apache.ws.commons.schema.XmlSchemaSerializer.XmlSchemaSerializerException;
import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.util.Assert;
import org.springframework.xml.validation.XmlValidator;
import org.springframework.xml.validation.XmlValidatorFactory;
import org.springframework.xml.xsd.XsdSchema;
import org.w3c.dom.Document;
/**
 * 修改人： Thomas
 * 修改内容：新增 
 * 类说明：.xsd文件解析
 */
public class CommonsXsdSchemaJWeb implements XsdSchema {
	
	private final XmlSchema schema ;
	
	private final XmlSchemaCollection collection ;
	
	protected CommonsXsdSchemaJWeb(XmlSchema schema){
		this(schema , null);
	}
	
	protected CommonsXsdSchemaJWeb(XmlSchema schema , XmlSchemaCollection collection){
		Assert.notNull(schema , "'schema' must not be null");
		this.schema = schema ; 
		this.collection = collection ;
	}
	
	public String getTargetNamespace(){
		return schema.getTargetNamespace();
	}
	
	public QName[] getElementNames(){
		ArrayList arrayList = new ArrayList();
		Iterator it = this.schema.getElements().getNames();
		while(it.hasNext()){
			QName qname = (QName) it.next();
			arrayList.add(qname);
		}
		return (QName[]) arrayList.toArray(new QName[arrayList.size()]);
	}
	
	public Source getSource(){
		
		try {
			XmlSchemaSerializer serializer = BeanUtils.instantiate(XmlSchemaSerializer.class);
			if(collection != null){
				serializer.setExtReg(collection.getExtReg());
			}  //serializeSchema(XmlSchema,boolean):Serialize an entire schema,returning an array of DOM Documents,one per XSL file.
			Document[] serializeSchemas = serializer.serializeSchema(schema , false);
			return new DOMSource(serializeSchemas[0]);
		} catch (BeanInstantiationException e) {
			
		} catch (XmlSchemaSerializerException e){
			
		}
		
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		schema.write(bos);
		
		ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
		return new StreamSource(bis);
	}
	
	public XmlValidator createValidator() throws IOException {
		Resource resource = new UrlResource(schema.getSourceURI());
		return XmlValidatorFactory.createValidator(resource , "http://www.w3.org/2001/XMLSchema");
	}
	
	public XmlSchema getSchema(){
		return schema ;
	}
	
	public String toString(){
		StringBuilder builder = new StringBuilder("CommonsXsdSchema");
		builder.append('{');
		builder.append(getTargetNamespace());
		builder.append('}');
		return builder.toString();
	}
}